﻿using System;
using System.IO;
using System.Linq;
using System.Text;
using FtpSupport;
using Enyim.Caching;
using Ayatta.Contract;
using System.Web.Mvc;
using Web.Core.Security;
using Web.Core.Extensions;
using System.Web.Security;
using System.Configuration;
using Web.Core.GameProxys;
using Web.Core.Components;
using Ayatta.Contract.Config;
using Web.Core.ActionResults;
using Ayatta.Contract.Domain;
using Ayatta.Common.Extension;
using System.Collections.Generic;
using Ayatta.Common.Configuration;
using System.Web.Script.Serialization;

namespace Web.Core.Controllers
{
    public abstract class CoreController : Controller
    {
        protected Lazy<IInfrastructureService> Infrastructure { get; private set; }
        protected Lazy<IPassportService> Passport { get; private set; }
        protected Lazy<IAccountService> Account { get; private set; }
        protected Lazy<IStoreService> Store { get; private set; }
        protected Lazy<ITradeService> Trade { get; private set; }
        protected Lazy<IPlayService> Play { get; private set; }
        protected Lazy<IMiscService> Misc { get; private set; }
        protected Lazy<IExtraService> Extra { get; private set; }

        protected static IMemcachedClient MemcachedClient { get; private set; }

        protected static string DefaultUrl = WebSite.Main;
        private const string CategoryService = "CategoryService";

        protected static readonly string AesKey = ConfigurationManager.AppSettings["Aes.Key"];
        protected static readonly string PasswordSalt = ConfigurationManager.AppSettings["Password.Salt"];

        protected static readonly string[] CaptchaKey = new[] { "signin", "signup", "pwd.reset", };

        protected CoreController(Lazy<IInfrastructureService> infrastructure, Lazy<IPassportService> passport, Lazy<IAccountService> account, Lazy<IStoreService> store, Lazy<ITradeService> trade, Lazy<IPlayService> play, Lazy<IMiscService> misc, Lazy<IExtraService> extra, IMemcachedClient memcachedClient)
        {
            Infrastructure = infrastructure;
            Passport = passport;
            Account = account;
            Store = store;
            Trade = trade;
            Play = play;
            Misc = misc;
            Extra = extra;
            MemcachedClient = memcachedClient;
            UserAddress.GetAreaName = AreaName;
        }

        protected ActionResult Jsonp<T>(T data, string callback)
        {
            return new JsonpResult<T>(data, callback);
        }

        /// <summary>
        /// 设置登录Cookie
        /// </summary>
        /// <param name="userName">用户名</param>
        /// <param name="createPersistentCookie"></param>
        /// <param name="identity"></param>
        protected void SetAuthCookie(string userName, bool createPersistentCookie, Identity identity)
        {
            var userData = new JavaScriptSerializer().Serialize(identity);
            var authCookie = FormsAuthentication.GetAuthCookie(userName, createPersistentCookie);
            var ticket = FormsAuthentication.Decrypt(authCookie.Value);
            var newTicket = new FormsAuthenticationTicket(ticket.Version, ticket.Name, ticket.IssueDate,
                                                          ticket.Expiration, ticket.IsPersistent, userData);
            authCookie.Value = FormsAuthentication.Encrypt(newTicket);
            if (createPersistentCookie)
            {
                authCookie.Expires = DateTime.Now.AddDays(14);
            }
            Response.Cookies.Add(authCookie);
        }

        protected bool CaptchaValidateInternal(string captchaKey, string captchaText)
        {
            if (CaptchaKey.Contains(captchaKey))
            {
                if (Session != null)
                {
                    if (Session[captchaKey] != null)
                    {
                        return Session[captchaKey].ToString() == captchaText.ToLower();
                    }
                    return false;
                }
                return false;
            }
            return false;
        }

        private IGameClient GetGameClient(int gameId)
        {
            var client = GameClientFactory.Create(gameId);
            //client.Updated += UpdateUserInfo;
            return client;
        }

        /// <summary>
        /// 获取用户地址库
        /// </summary>
        /// <param name="userId"></param>
        /// <returns></returns>
        protected IList<UserAddress> UserAddressList(int userId)
        {
            if (userId < 0) return null;
            var key = string.Format(CacheKey.Passport.User.Address, userId);
            return CachePut(key, () => Passport.Value.UserAddressList(userId));
        }

        /// <summary>
        /// 获取标准行政区域
        /// </summary>
        /// <returns></returns>
        protected IList<Area> AreaList()
        {
            var key = CacheKey.InfrastructureService.Areas;
            return CachePut(key, () => Infrastructure.Value.AreaList());
        }

        protected string AreaName(string id, IList<Area> areas)
        {
            var len = id.Length;
            string province, city;
            if (len == 2)
            {
                province = areas.First(o => o.Id == id).Name;
                return province;
            }
            if (len == 4)
            {
                var area = areas.First(o => o.Id == id);
                city = area.Name;
                province = areas.First(o => o.Id == area.ParentId).Name;
                return province + " " + city;
            }
            if (len == 6)
            {
                var area = areas.First(o => o.Id == id);
                var district = area.Name;
                area = areas.First(o => o.Id == area.ParentId);
                city = area.Name;
                area = areas.First(o => o.Id == area.ParentId);
                province = area.Name;
                return province + " " + city + " " + district;
            }
            return string.Empty;
        }


        protected Magic<string, string, string> AreaFullName(string id, IList<Area> areas)
        {
            var len = id.Length;
            string province, city;
            if (len == 2)
            {
                province = areas.First(o => o.Id == id).Name;
                return new Magic<string, string, string>(province, string.Empty, string.Empty);
            }
            if (len == 4)
            {
                var area = areas.First(o => o.Id == id);
                city = area.Name;
                province = areas.First(o => o.Id == area.ParentId).Name;
                return new Magic<string, string, string>(province, city, string.Empty);

            }
            if (len == 6)
            {
                var area = areas.First(o => o.Id == id);
                var district = area.Name;
                area = areas.First(o => o.Id == area.ParentId);
                city = area.Name;
                area = areas.First(o => o.Id == area.ParentId);
                province = area.Name;
                return new Magic<string, string, string>(province, city, district);
            }
            return new Magic<string, string, string>(string.Empty, string.Empty, string.Empty);
        }

        /// <summary>
        /// 获取所有物流公司
        /// </summary>
        /// <returns></returns>
        protected IList<LogisticsCompany> LogisticsCompanyList()
        {
            var key = CacheKey.InfrastructureService.LogisticsCompanies;
            return CachePut(key, () => Infrastructure.Value.LogisticsCompanyList());
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        protected IList<CategoryGroup> CategoryGroupList(int group)
        {
            var key = string.Format(CacheKey.Store.CategoryGroup, group);
            return CachePut(key, () => Store.Value.CategoryGroupList(group));
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        protected IList<ProductCategory> ProductCategoryList(int parentId)
        {
            var key = string.Format(CacheKey.Store.ProductCategory, parentId);
            return CachePut(key, () => Store.Value.ProductCategoryList(parentId));
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        protected IList<ProductCategoryProp> ProductCategoryPropList(int categoryId)
        {
            var key = string.Format(CacheKey.Store.ProductCategoryProp, categoryId);
            return CachePut(key, () => Store.Value.ProductCategoryPropList(categoryId));
        }
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        protected IList<ProductCategoryPropValue> ProductCategoryPropValueList(int categoryId)
        {
            var key = string.Format(CacheKey.Store.ProductCategoryPropValue, categoryId);
            return CachePut(key, () => Store.Value.ProductCategoryPropValueList(categoryId));
        }

        protected static string IdGenerate(DateTime time, int buyerId, int sellerId = 0)
        {
            var sb = new StringBuilder(3);
           
            sb.Append(time.ToString("yyMMddHHmmssffffff"));
            sb.Append((buyerId % 64).ToString("00"));
            sb.Append((sellerId % 64).ToString("00"));
            return sb.ToString();
        }
        #region Memcached

        /// <summary>
        /// 向Memcached写入缓存
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key">缓存Key</param>
        /// <param name="func"></param>
        /// <returns></returns>
        protected T CachePut<T>(string key, Func<T> func) where T : class
        {
            return MemcachedClient.Put(key, func);
        }

        /// <summary>
        /// 向Memcached写入缓存
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key">缓存Key</param>
        /// <param name="func"></param>
        /// <param name="expiresAt"></param>
        /// <returns></returns>
        protected T CachePut<T>(string key, Func<T> func, DateTime expiresAt) where T : class
        {
            return MemcachedClient.Put(key, func, expiresAt);
        }

        /// <summary>
        /// 从Memcached缓存中移除
        /// </summary>
        /// <param name="key">Key</param>
        protected void CacheRemove(string key)
        {
            MemcachedClient.Remove(key);
        }

        #endregion

        #region Ftp上传

        /// <summary>
        /// ftp上传
        /// </summary>
        /// <param name="stream">文件流</param>
        /// <param name="directory">目录以/开始以/结束</param>
        /// <param name="fileName">文件名</param>
        /// <returns>返回远程文件URI</returns>
        protected MagicKit<string> FtpUpload(Stream stream, string directory, string fileName)
        {
            var result = new MagicKit<string>();
            var ftp = ConfigurationManager.GetSection("ftp") as FtpConfigurationSetion;
            if (ftp != null)
            {
                var file = ftp.Server + directory + fileName;
                using (var conn = new FtpConnection())
                {
                    var temp = string.Empty;
                    try
                    {
                        conn.Connect(ftp.Ip, ftp.UserName, ftp.Password);
                        foreach (var o in directory.Split('/'))
                        {
                            temp += string.Format("{0}/", o);
                            if (!conn.DirectoryExist(temp))
                            {
                                conn.CreateDirectory(temp);
                            }
                        }
                        conn.SetCurrentDirectory(directory);
                        conn.PutStream(stream, fileName);

                        result.Status = true;
                        result.Data = file;
                    }
                    catch (Exception e)
                    {
                        result.Message = e.Message;
                    }
                }
            }
            else
            {
                result.Message = "Ftp配置文件错误！";
            }
            return result;
        }

        #endregion

        #region 获取客户端信息

        /// <summary>
        /// 获取客户端UserAgent
        /// </summary>
        /// <returns></returns>
        protected string GetUserAgent()
        {
            var osVersion = "未知";

            var userAgent = Request.UserAgent ?? string.Empty;

            if (!userAgent.IsNullOrEmpty())
            {
                if (userAgent.Contains("NT 6.1"))
                {
                    osVersion = "Windows 7";
                }
                else if (userAgent.Contains("NT 6.0"))
                {
                    osVersion = "Windows Vista/Server 2008";
                }
                else if (userAgent.Contains("NT 5.2"))
                {
                    osVersion = "Windows Server 2003";
                }
                else if (userAgent.Contains("NT 5.1"))
                {
                    osVersion = "Windows XP";
                }
                else if (userAgent.Contains("NT 5"))
                {
                    osVersion = "Windows 2000";
                }
                else if (userAgent.Contains("NT 4"))
                {
                    osVersion = "Windows NT4";
                }
                else if (userAgent.Contains("Me"))
                {
                    osVersion = "Windows Me";
                }
                else if (userAgent.Contains("98"))
                {
                    osVersion = "Windows 98";
                }
                else if (userAgent.Contains("95"))
                {
                    osVersion = "Windows 95";
                }
                else if (userAgent.Contains("Mac"))
                {
                    osVersion = "Mac";
                }
                else if (userAgent.Contains("Unix"))
                {
                    osVersion = "UNIX";
                }
                else if (userAgent.Contains("Linux"))
                {
                    osVersion = "Linux";
                }
                else if (userAgent.Contains("SunOS"))
                {
                    osVersion = "SunOS";
                }
            }
            return osVersion;
        }

        /// <summary>
        ///  获取客户端浏览器名称 版本号
        /// </summary>
        /// <returns></returns>
        protected string GetBrowser()
        {
            var browser = Request.Browser;
            return browser.Browser + browser.Version;
        }

        /// <summary>
        /// 获取客户端IpAddress
        /// </summary>
        /// <returns></returns>
        protected string GetIpAddress()
        {
            var result = Request.ServerVariables["HTTP_X_FORWARDED_FOR"];
            result = string.IsNullOrEmpty(result) ? Request.ServerVariables["REMOTE_ADDR"] : Request.UserHostAddress;
            return result;
        }

        /// <summary>
        /// 获取客户端上次请求的 URL 的信息
        /// </summary>
        /// <returns></returns>
        protected string GetUrlReferrer()
        {
            var referrer = Request.UrlReferrer;
            return referrer != null ? referrer.ToString() : string.Empty;
        }

        #endregion
    }
}
